using System;
using System.Collections.Generic;
using System.Text;
using virtuaPol.Util;

namespace virtuaPol.Model
{
    [Serializable]
    [System.Xml.Serialization.XmlType("country")]
    public class CCountry : IComparable<CCountry>, virtuaPol.Util.INamedObject
    {
        // Locker object for thread safety
        private object _locker = new object();

        private string name;
        [System.Xml.Serialization.XmlAttribute("name")]
        public string Name
        {
            get { lock (_locker) { return name; } }
            set { lock (_locker) { name = value; } }
        }

        private string description;
        [System.Xml.Serialization.XmlElement("description")]
        public string Description
        {
            get { lock (_locker) { return description; } }
            set { lock (_locker) { description = value; } }
        }

        private bool playable = false;
        [System.Xml.Serialization.XmlAttribute("playable")]
        public bool Playable
        {
            get { lock (_locker) { return playable; } }
            set { lock (_locker) { playable = value; } }
        }

        private ExtendedList<CPerson> persons;
        [System.Xml.Serialization.XmlArray("persons")]
        public ExtendedList<CPerson> Persons
        {
            get { lock (_locker) { return persons; } }
            set { lock (_locker) { persons = value; } }
        }

        private ExtendedList<CProperty> properties;
        [System.Xml.Serialization.XmlArray("properties")]
        public ExtendedList<CProperty> Properties
        {
            get { lock (_locker) { return properties; } }
            set { lock (_locker) { properties = value; } }
        }

        private ExtendedList<CCountryRelation> relations = new ExtendedList<CCountryRelation>();
        [System.Xml.Serialization.XmlArray("relations")]
        public ExtendedList<CCountryRelation> Relations
        {
            get { lock (_locker) { return relations; } }
            set { lock (_locker) { relations = value; } }
        }

        public CCountry()
        {
            Persons = new ExtendedList<CPerson>();
            Persons.ElementAdded += new EventHandler<ListChangedEventArgument<CPerson>>(persons_ElementAdded);
            Persons.ElementDeleted += new EventHandler<ListChangedEventArgument<CPerson>>(persons_ElementDeleted);
            Properties = new ExtendedList<CProperty>();
        }

        public CCountry(string name)
        {
            Name = name;
            Persons = new ExtendedList<CPerson>();
            Persons.ElementAdded += new EventHandler<ListChangedEventArgument<CPerson>>(persons_ElementAdded);
            Persons.ElementDeleted += new EventHandler<ListChangedEventArgument<CPerson>>(persons_ElementDeleted);
            Properties = new ExtendedList<CProperty>();
        }

        private void persons_ElementAdded(object sender, ListChangedEventArgument<CPerson> e)
        {
            e.Element.Country = this;
        }

        private void persons_ElementDeleted(object sender, ListChangedEventArgument<CPerson> e)
        {
            e.Element.Country = null;
        }

        public int CompareTo(CCountry other)
        {
            return Name.CompareTo(other.Name);
        }

        public void addPerson(CPerson p)
        {
            Persons.Add(p);
        }

        public CPerson removePerson(CPerson p)
        {
            Persons.Remove(p);
            return p;
        }

        public CPerson getPersonByName(string name)
        {
            if (Persons.Contains(name))
                return Persons[name];
            else
                return null;
        }

        public CPerson getPersonByIndex(int index)
        {
            return Persons[index];
        }

        public void addProperty(CProperty p)
        {
            Properties.Add(p);
        }

        public CProperty removeProperty(CProperty p)
        {
            Properties.Remove(p);
            return p;
        }

        public CProperty getPropertyByName(string name)
        {
            if (Properties.Contains(name))
                return Properties[name];
            else
                return null;
        }

        public CProperty getPropertyByIndex(int index)
        {
            return Properties[index];
        }

        public bool addRelation(CCountryRelation r)
        {
            bool result;
            try
            {
                Relations.Add(r);
                result = true;
            }
            catch (Exception ex)
            {
                result = false;
            }
            return result;
        }

        public CCountryRelation removeRelation(CCountryRelation r)
        {
            Relations.Remove(r);
            return r;
        }

        public CCountryRelation getRelationByName(string name)
        {
            if (Relations.Contains(name))
                return Relations[name];
            else
                return null;
        }

        public CCountryRelation getRelationByIndex(int index)
        {
            return Relations[index];
        }
    }
}
